using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using RadioTimer.Models;
using RadioTimer.Services;
using System.Collections.ObjectModel;
using System.Windows.Input;

namespace RadioTimer.ViewModels
{
    /// <summary>
    /// 设置页面视图模型类
    /// 继承自BaseViewModel，负责设置页面的数据绑定和业务逻辑处理
    /// 提供24小时报时设置的管理、批量操作和数据持久化功能
    /// 符合MVVM架构模式，支持双向数据绑定和命令模式
    /// </summary>
    public partial class SettingsPageViewModel : BaseViewModel
    {
        #region 私有字段

        /// <summary>
        /// 数据存储服务实例，用于持久化设置数据
        /// </summary>
        private readonly IDataStorageService _dataStorage;

        /// <summary>
        /// 应用程序设置的私有字段
        /// </summary>
        [ObservableProperty]
        private AppSettings _appSettings = new();

        /// <summary>
        /// 批量操作锁，防止并发修改
        /// </summary>
        private readonly object _batchOperationLock = new object();

        #endregion

        #region 构造函数

        /// <summary>
        /// 初始化SettingsPageViewModel实例
        /// 通过依赖注入获取所需的服务实例
        /// </summary>
        /// <param name="dataStorage">数据存储服务</param>
        public SettingsPageViewModel(IDataStorageService dataStorage)
        {
            _dataStorage = dataStorage;
            InitializeHourlySettings();
            
            // 记录日志
            Services.DebugLogger.WriteLine("SettingsPageViewModel 初始化完成");
        }

        #endregion

        #region 公共属性

        /// <summary>
        /// 获取24小时设置的可观察集合
        /// 用于在UI中显示和编辑每个小时的报时设置
        /// 支持数据绑定和集合变更通知
        /// </summary>
        public ObservableCollection<TimeChimeSettings> HourlySettingsList { get; } = new();

        #endregion

        #region RelayCommand 命令

        /// <summary>
        /// 保存设置的命令
        /// 绑定到保存按钮，将当前设置持久化到本地存储
        /// </summary>
        [RelayCommand]
        private async Task SaveSettingsAsync()
        {
            if (IsBusy) return;

            try
            {
                Services.DebugLogger.WriteLine("开始保存设置数据");
                IsBusy = true;

                // 将列表中的设置同步到AppSettings的字典中
                AppSettings.HourlySettings.Clear();
                foreach (var setting in HourlySettingsList)
                {
                    AppSettings.HourlySettings[setting.Hour] = setting;
                }

                // 保存到本地存储
                await _dataStorage.SaveAppSettingsAsync(AppSettings);
                
                // 显示成功提示
                await ToastService.ShowToastAsync("设置已保存");
            }
            catch (Exception ex)
            {
                Services.DebugLogger.WriteError($"Error saving settings: {ex.Message}");
                await ToastService.ShowToastAsync("保存设置失败");
            }
            finally
            {
                IsBusy = false;
            }
        }

        /// <summary>
        /// 重置设置的命令
        /// 绑定到重置按钮，将所有设置恢复为默认值
        /// </summary>
        [RelayCommand]
        private async Task ResetSettingsAsync()
        {
            if (IsBusy) return;

            try
            {
                Services.DebugLogger.WriteLine("开始重置设置数据");
                IsBusy = true;

                // 创建新的默认设置
                AppSettings = new AppSettings();
                // 保存默认设置
                await _dataStorage.SaveAppSettingsAsync(AppSettings);
                // 重新加载设置到UI
                await LoadSettingsAsync();
                
                // 显示成功提示
                await ToastService.ShowToastAsync("设置已重置");
            }
            catch (Exception ex)
            {
                Services.DebugLogger.WriteError($"Error resetting settings: {ex.Message}");
                await ToastService.ShowToastAsync("重置设置失败");
            }
            finally
            {
                IsBusy = false;
            }
        }

        /// <summary>
        /// 启用所有小时设置的命令
        /// </summary>
        [RelayCommand]
        private async Task EnableAllHoursAsync()
        {
            if (IsBusy) return;

            try
            {
                Services.DebugLogger.WriteLine("开始启用所有小时设置");
                IsBusy = true;

                lock (_batchOperationLock)
                {
                    var settingsArray = HourlySettingsList.ToArray();

                    foreach (var setting in settingsArray)
                    {
                        setting.IsEnabled = true;
                    }
                }
                
                // 显示成功提示
                await ToastService.ShowToastAsync("已启用所有小时设置");
            }
            catch (Exception ex)
            {
                Services.DebugLogger.WriteError($"Error enabling all hours: {ex.Message}");
                await ToastService.ShowToastAsync("启用所有小时设置失败");
            }
            finally
            {
                IsBusy = false;
            }
        }

        /// <summary>
        /// 禁用所有小时设置的命令
        /// </summary>
        [RelayCommand]
        private async Task DisableAllHoursAsync()
        {
            if (IsBusy) return;

            try
            {
                Services.DebugLogger.WriteLine("开始禁用所有小时设置");
                IsBusy = true;

                lock (_batchOperationLock)
                {
                    var settingsArray = HourlySettingsList.ToArray();

                    foreach (var setting in settingsArray)
                    {
                        setting.IsEnabled = false;
                    }
                }
                
                // 显示成功提示
                await ToastService.ShowToastAsync("已禁用所有小时设置");
            }
            catch (Exception ex)
            {
                Services.DebugLogger.WriteError($"Error disabling all hours: {ex.Message}");
                await ToastService.ShowToastAsync("禁用所有小时设置失败");
            }
            finally
            {
                IsBusy = false;
            }
        }

        /// <summary>
        /// 设置工作时间的命令
        /// </summary>
        [RelayCommand]
        private async Task SetWorkingHoursAsync()
        {
            if (IsBusy) return;

            try
            {
                Services.DebugLogger.WriteLine("开始设置工作时间");
                IsBusy = true;

                lock (_batchOperationLock)
                {
                    var settingsArray = HourlySettingsList.ToArray();

                    foreach (var setting in settingsArray)
                    {
                        setting.IsEnabled = setting.Hour >= 9 && setting.Hour <= 17;
                    }
                }
                
                // 显示成功提示
                await ToastService.ShowToastAsync("已设置工作时间（9-17点）");
            }
            catch (Exception ex)
            {
                Services.DebugLogger.WriteError($"Error setting working hours: {ex.Message}");
                await ToastService.ShowToastAsync("设置工作时间失败");
            }
            finally
            {
                IsBusy = false;
            }
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 初始化24小时设置列表
        /// 为每个小时（0-23）创建默认的TimeChimeSettings对象
        /// </summary>
        public void InitializeHourlySettings()
        {
            HourlySettingsList.Clear();
            for (int hour = 0; hour < 24; hour++)
            {
                HourlySettingsList.Add(new TimeChimeSettings { Hour = hour });
            }
        }

        /// <summary>
        /// 异步加载设置数据
        /// 从本地存储中读取保存的设置，并更新UI显示
        /// 优化性能，防止ANR
        /// </summary>
        /// <returns>异步任务</returns>
        public async Task LoadSettingsAsync()
        {
            if (IsBusy) return;

            try
            {
                Services.DebugLogger.WriteLine("开始加载设置数据");
                IsBusy = true;

                Services.DebugLogger.WriteLine("从存储中加载应用设置");
                // 从存储中加载应用设置
                var settings = await _dataStorage.LoadAppSettingsAsync().ConfigureAwait(false);

                AppSettings = settings;

                // 批量更新集合，减少UI通知
                HourlySettingsList.Clear();

                // 按小时顺序添加设置到列表中
                var sortedSettings = settings.HourlySettings
                    .OrderBy(x => x.Key)
                    .Select(x => x.Value)
                    .ToList();

                foreach (var setting in sortedSettings)
                {
                    HourlySettingsList.Add(setting);
                }
            }
            catch (Exception uiEx)
            {
                Services.DebugLogger.WriteError($"Error updating UI: {uiEx.Message}");
                // 如果UI更新失败，初始化默认设置
                InitializeHourlySettings();
            }
            finally
            {
                IsBusy = false;
            }
        }

        #endregion

        #region 公共方法（批量操作）

        /// <summary>
        /// 设置全局音量
        /// 批量操作方法，将所有小时的报时音量设置为指定值
        /// </summary>
        /// <param name="volume">音量值，范围0.0-1.0</param>
        public async Task SetGlobalVolumeAsync(double volume)
        {
            if (IsBusy) return;

            try
            {
                Services.DebugLogger.WriteLine($"开始设置全局音量: {volume}");
                IsBusy = true;

                lock (_batchOperationLock)
                {
                    var settingsArray = HourlySettingsList.ToArray();

                    foreach (var setting in settingsArray)
                    {
                        setting.Volume = volume;
                    }
                }
                
                // 显示成功提示
                await ToastService.ShowToastAsync($"全局音量已设置为 {volume:P0}");
            }
            catch (Exception ex)
            {
                Services.DebugLogger.WriteError($"Error setting global volume: {ex.Message}");
                await ToastService.ShowToastAsync("设置全局音量失败");
            }
            finally
            {
                IsBusy = false;
            }
        }

        /// <summary>
        /// 设置全局重复播放次数
        /// 批量操作方法，将所有小时的重复播放次数设置为指定值
        /// </summary>
        /// <param name="count">重复次数，范围1-5</param>
        public async Task SetGlobalRepeatCountAsync(int count)
        {
            if (IsBusy) return;

            try
            {
                Services.DebugLogger.WriteLine($"开始设置全局重复播放次数: {count}");
                IsBusy = true;

                lock (_batchOperationLock)
                {
                    var settingsArray = HourlySettingsList.ToArray();

                    foreach (var setting in settingsArray)
                    {
                        setting.RepeatCount = count;
                    }
                }
                
                // 显示成功提示
                await ToastService.ShowToastAsync($"全局重复次数已设置为 {count}");
            }
            catch (Exception ex)
            {
                Services.DebugLogger.WriteError($"Error setting global repeat count: {ex.Message}");
                await ToastService.ShowToastAsync("设置全局重复次数失败");
            }
            finally
            {
                IsBusy = false;
            }
        }

        #endregion
    }
}